//
//  SHToastView.m
//  SHFoundation
//
//  Created by Guanglu on 19/3/2019.
//

#import "SHToastView.h"
#import "UICategory.h"

#import <objc/message.h>

//#import "SHLog.h"

const NSTimeInterval kSHToastDefaultDuration = 2.f;

const CGFloat kToastPaddingVertical          = 13.f;
const CGFloat kToastPaddingHorizon           = 25.f;
const CGFloat kToastBottomPositonMaginBottom = 60.f;
const CGFloat kToastTopPositonMaginTop       = 60.f;


@interface SHToastView ()

@property (nonatomic) NSTimeInterval duration;
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) NSDictionary *textAttributes;
@property (nonatomic) CGSize labelSize;

@end

@implementation SHToastView

+ (instancetype)toastWithText:(NSString *)text position:(SHToastPosition)position duration:(NSTimeInterval)duration dismissHandler:(void (^)(void))handler {
    return [[self alloc] initWithText:text position:position duration:duration dismissHandler:handler];
}

+ (instancetype)toastWithText:(NSString *)text dismissHandler:(void (^)(void))handler {
    return [self toastWithText:text
                      position:SHToastPositionCenter
                      duration:kSHToastDefaultDuration
                dismissHandler:handler];
}

+ (instancetype)toastWithText:(NSString *)text {
    return [self toastWithText:text position:SHToastPositionCenter duration:kSHToastDefaultDuration dismissHandler:nil];
}

- (instancetype)initWithText:(NSString *)text position:(SHToastPosition)position duration:(NSTimeInterval)duration dismissHandler:(void (^)(void))handler {
    self = [self initWithText:text];
    if (self) {
        self.position   = position;
        _duration       = duration;
        _dismissHandler = handler;
    }
    return self;
}

- (instancetype)initWithText:(NSString *)text dismissHandler:(void (^)(void))handler {
    self = [self initWithText:text];
    if (self) {
        _dismissHandler = handler;
    }
    return self;
}

- (instancetype)initWithText:(NSString *)text {
    self = [self init];
    if (self) {
        
        if ([text respondsToSelector:@selector(stringByTrimmingCharactersInSet:)]) {
            _text = [text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
        }
        _duration = kSHToastDefaultDuration;

        NSMutableParagraphStyle *paragraphStyle = NSMutableParagraphStyle.new;
        paragraphStyle.alignment = NSTextAlignmentCenter;
        _textAttributes = @{
            NSFontAttributeName : [UIFont systemFontOfSize:14.0f],
            NSForegroundColorAttributeName : UIColor.whiteColor,
            NSParagraphStyleAttributeName : paragraphStyle
        };

        _labelSize = [_text boundingRectWithSize:CGSizeMake(UIScreen.screenWidth * 0.75, 500)
                                        options:NSStringDrawingUsesLineFragmentOrigin
                                     attributes:self.textAttributes
                                        context:nil].size;

        [self setup];
        self.position = SHToastPositionCenter;
    }
    return self;
}

+ (instancetype)showWithText:(NSString*)text {
    
    if (![text isKindOfClass:[NSString class]] || text.length < 1) {
        return nil;
    }
    
    SHToastView *toastView = [[self alloc] initWithText:text];
    [toastView show];
    return toastView;
}



- (void)show {
    // 长度小于1的内容，直接toast
    NSString *showText = [_text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (showText.length < 1) {
        if (self.dismissHandler) {
            self.dismissHandler();
        }
//        SHLogWarning(@"Toast没内容要显示啊...");
        return;
    }
    
    UIWindow *nowWindow = self.appWindow;
    for (UIView *view in nowWindow.subviews) {
        if ([view isKindOfClass:self.class]) {
            [view removeFromSuperview];
        }
    }
    [nowWindow addSubview:self];
    
    self.alpha = 0;
    __weak __typeof(self) weakSelf = self;
    [UIView animateKeyframesWithDuration:self.duration delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionCurveLinear
                              animations:^{
          [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.1 animations:^{
              __strong __typeof(weakSelf) strongSelf = weakSelf;
              strongSelf.alpha = 1;
          }];

          [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.85 animations:^{
              __strong __typeof(weakSelf) strongSelf = weakSelf;
              strongSelf.alpha = 1;
          }];

          [UIView addKeyframeWithRelativeStartTime:0.85 relativeDuration:0.15 animations:^{
              __strong __typeof(weakSelf) strongSelf = weakSelf;
              strongSelf.alpha = 0;
          }];
    } completion:^(BOOL finished) {
        __strong __typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf removeFromSuperview];
        if (strongSelf.dismissHandler) {
            strongSelf.dismissHandler();
        }
    }];
}

- (void)showInController:(UIViewController*)viewController {
    for (UIView *view in viewController.view.subviews) {
        if ([view isKindOfClass:self.class]) {
            [view removeFromSuperview];
        }
    }
    [viewController.view addSubview:self];
    
    self.alpha = 0;
    __weak __typeof(self) weakSelf = self;
    [UIView animateKeyframesWithDuration:self.duration delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionCurveLinear
                              animations:^{
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.1 animations:^{
            __strong __typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.alpha = 1;
        }];
                                  
        [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.85 animations:^{
            __strong __typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.alpha = 1;
        }];
                                  
        [UIView addKeyframeWithRelativeStartTime:0.85 relativeDuration:0.15 animations:^{
            __strong __typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.alpha = 0;
        }];
    } completion:^(BOOL finished) {
        __strong __typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf removeFromSuperview];
        if (strongSelf.dismissHandler) {
            strongSelf.dismissHandler();
        }
    }];
}

#pragma mark - setter
- (void)setPosition:(SHToastPosition)position {
    _position = position;
    UIWindow *window = self.appWindow;
    switch (position) {
        case SHToastPositionBottom:
            self.frame = CGRectMake((UIScreen.screenWidth - self.width) / 2,
                                    UIScreen.screenHeight - kToastBottomPositonMaginBottom - self.height, self.width,
                                    self.height);
            break;
        case SHToastPositionTop:
            self.frame =
                CGRectMake((UIScreen.screenWidth - self.width) / 2, kToastTopPositonMaginTop, self.width, self.height);
            break;

        default:
            self.center = CGPointMake(window.width / 2, window.height / 2);
            break;
    }
}

/// 获取应用的window, 如果其它地方new一个Window然后makeKeyWindow的话，toast可能展示不出来
- (UIWindow*)appWindow {
    NSObject *appDelegate = UIApplication.sharedApplication.delegate;
    if ([appDelegate respondsToSelector:@selector(window)]) {
        id appWindow = ((id (*)(id, SEL))objc_msgSend)(appDelegate, @selector(window));
        if ([appWindow isKindOfClass:UIWindow.class]) {
            return (UIWindow*)appWindow;
        }
    }
    return  UIApplication.sharedApplication.keyWindow;
}

#pragma mark - private
- (void)setup {
    self.frame = CGRectMake(0, 0, self.labelSize.width + kToastPaddingHorizon * 2, self.labelSize.height + kToastPaddingVertical * 2);
    self.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.8];
    self.layer.cornerRadius = 5.0f;
    self.layer.masksToBounds = YES;
}

#pragma mark - draw
- (void)drawRect:(CGRect)rect {
    [_text drawInRect:CGRectMake((rect.size.width - _labelSize.width) / 2, (rect.size.height - _labelSize.height) / 2, _labelSize.width, _labelSize.height)
        withAttributes:_textAttributes];
}

@end
